/**
 *    Hi3861 GPIO PWM输出 播放音乐
 * 通道：PWM1  选择映射到GPIO8 （GPIO10也可）
 * 
 * 2021.08.30 By HelloKun 
 * 
 * */

#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "iot_gpio.h"
#include "hi_io.h"
#include "iot_pwm.h"
#include "hi_time.h"
#include "hi_pwm.h"

#define PWM_TASK_STACK_SIZE 512
#define PWM_TASK_PRIO 25
#define PWM1_TONE_GPIO 9
#define PWM1 0  //== hi_pwm.h 中定义了枚举类型 HI_PWM_PORT_PWM1 1

//B调 中音 频率 五音不全，找度娘滴
#define Do 495  //1 A
#define Re 556  //2 B
#define Mi 624  //3 C
#define Fa 661  //4 D
#define Sol 742 //5 E
#define La 833  //6 F
#define Si 935  //7 G
#define Do_h 990  //1^
#define Re_h 1112  //2^
#define Mi_h 1178  //3^
#define Fa_h 1322  //4^
#define Sol_h 1484 //5^
#define La_h 1665  //6^
#define Si_h 1869  //7^
#define Zero 1    //0495

int Happy_Birthday[] = {Sol, Sol, La, Sol, Do_h, Si,
                 Sol, Sol, La, Sol, Re_h, Do_h,
                 Sol, Sol, Sol_h, Mi_h, Do_h, Si, La,
                 Fa_h, Fa_h, Mi_h, Do_h, Re_h, Do_h
                }; //《生日快乐歌》曲谱
float duty_happy[] =
{
  0.5, 0.5, 1, 1, 1, 1 + 1,
  0.5, 0.5, 1, 1, 1, 1 + 1,
  0.5, 0.5, 1, 1, 1, 1, 1,
  0.5, 0.5, 1, 1, 1, 1 + 1,
};  //C调3/4节拍，控制音长  //遇到0过渡，把时间加在上一个音节

int Jay_Love[] = { Sol, Do_h, Si, Sol, Do,
                  Do, Sol, Re, Mi, Mi, Mi,
                  Mi, Sol, Do_h, Si, Sol, Do,
                  Do, Sol, Re, Mi, Fa, Mi,
                  Mi, Sol, Re_h, Do_h, Si, Do_h,
                  Do_h, Re_h, Mi_h, Do_h, Do_h, La,
                  La, Si, Do_h, Sol, Sol, Do,
                  Sol, Fa, Mi, Re, Do, Do,
                  Do, Si, Si,
                  Do_h, Do_h, Si, Do_h, Si, Do_h, Si, Do_h, Re_h, Mi_h,
                  Si, Si, La, Si, La, Si, La, Si, Do_h,
                  La, Do_h, Mi_h, Re_h, Do_h, Mi_h,
                  Mi_h, Mi_h, Mi_h, Re_h, Do_h,
                  Do_h, Do_h, Si, Do_h, Si, Do_h, Si, Do_h, Re_h, Mi_h,
                  Si, Si, La, Si, La, Si, La, Si, Do_h,
                  La, Do_h, Mi_h, Re_h, Do_h, Do_h,
                  Do_h, La, Si,
                  Do_h, Do_h, Do_h, Do_h, La, La, Si,
                  Do_h, Do_h, Do_h, Re_h, Re_h, Sol, La,
                  Si, Si, Si, Si, Sol, Sol, La,
                  Si, Si, Si, Do_h, Do_h, Do_h, Do_h, Re_h,
                  Mi_h, Mi_h, Mi_h, La, Do_h, Do_h, Re_h,
                  Mi_h, Mi_h, La_h, Mi_h, Re_h, Do_h, Do_h, Re_h,
                  Mi_h, Mi_h, Mi_h, Mi_h, Do_h, Mi_h, Re_h,
                  Re_h, Sol, Fa_h, Mi_h,
                  Mi_h, Fa_h, Mi_h, Re_h, Re_h,
                  Do_h, Re_h, Mi_h, Do_h, Do_h,
                  La, Do_h, Sol_h, Do_h, Mi_h, Mi_h,
                  Mi_h, Sol, Fa_h, Mi_h,
                  Mi_h, Fa_h, Mi_h, Re_h, Re_h,
                  Do_h, Re_h, Mi_h, La_h, La_h,
                  Sol_h, Si, Do_h, Re_h, Re_h, Do_h,
                  Do_h, Do_h, Re_h,
                  Mi_h, Sol_h, Re_h,
                  Do_h, Sol_h, Si, Si, Si,
                  La, Si, Do_h, Re_h,
                  Mi_h, Sol, Do_h, Re_h,
                  Mi_h, Sol_h, Re_h,
                  Do_h, Mi_h, Si, Si, Si,
                  La, Si, Do_h, Re_h,
                  Do_h,

                }; //《告白气球》曲谱

float duty_love[] =
{
  1, 0.5, 0.5, 0.5, 0.5,
  1, 0.5, 1, 0.5, 0.5, 0.5,
  1, 0.5 + 0.5, 0.5, 0.5, 0.5, 0.5,
  1, 0.5, 1, 0.5, 0.5, 0.5,
  1, 0.5 + 0.5, 0.5, 0.5, 0.5, 0.5,
  1, 0.5, 1, 0.5, 0.5, 0.5,
  1, 0.5, 1, 0.5, 0.5, 0.5,
  0.5, 0.5, 0.5, 1, 0.5, 1,
  1 + 0.5, 0.5, 1 + 1,
  0.5, 0.25, 0.25, 0.5, 0.5, 0.25, 0.25, 0.5 + 0.5, 0.25, 0.25,
  0.5, 0.25, 0.25, 0.5, 0.5, 0.25, 0.25, 0.5 + 0.5, 0.5 + 1,
  0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
  1 + 1 + 0.5, 0.5, 0.5, 0.25, 0.25 + 0.25,
  0.25, 0.25, 0.25, 0.5 + 0.25, 0.25, 0.25, 0.25, 0.5 + 0.5, 0.25, 0.25 + 0.25,
  0.25, 0.25, 0.25, 0.5 + 0.25, 0.25, 0.25, 0.25, 0.5 + 0.5, 0.5 + 1,
  0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
  1 + 1 + 1, 0.5, 0.5,
  0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5,
  0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5,
  0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5,
  0.5, 0.5, 0.5, 0.5, 0.25 + 0.5, 0.25, 0.5, 0.5,
  0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5,
  0.5, 0.5, 0.5, 0.25, 0.25, 1, 0.5, 0.5,
  0.5, 0.5, 0.5, 1, 0.5, 0.5, 0.5,
  1 + 1 + 0.5, 0.5, 0.5, 0.5,
  1, 0.5, 1, 0.5, 1,
  1, 0.5, 1, 0.5, 1,
  1, 0.5, 1, 0.5, 0.5, 0.5,
  1 + 1 + 0.5, 0.5, 0.5, 0.5,
  1, 0.5, 1, 0.5, 1,
  1, 0.5, 1, 0.5, 1,
  1, 0.5, 1, 0.5, 0.5, 0.5,
  1 + 1 + 1, 0.5, 0.5,
  1, 1, 1, 1 + 1,
  1, 1, 1, 0.5, 0.5,
  1, 1, 1 + 0.5, 0.5,
  1 + 1 + 0.5, 0.5, 0.5, 0.5,
  1, 1, 1 + 1,
  1, 1, 1 + 0.5, 0.25, 0.25,
  1, 1, 1 + 0.5, 0.5,
  1 + 1 + 1 + 1,
}; //B 4/4节拍

//音乐周期长
int length_1;  //==Happy_Birthday
int length_2;  //==小星星
int length_3;  //==南山南
int length_4;  //==告白气球

static void PwmMusicTask(void *arg)
{
    (void) arg;
    hi_pwm_set_clock(PWM_CLK_XTAL); // 设置时钟源为晶体时钟（40MHz，默认时钟源160MHz）
    while(1)
    {
        int val=0;
        for (val=0;val<length_1;val++)
        {
            //IoTPwmStart(PWM1,90,Happy_Birthday[val]*100);
            hi_pwm_start(0, 20000, Happy_Birthday[val]*130); //官方函数
            osDelay(duty_happy[val]*50);  //==50用于调整节拍节奏快慢 根据喜好调
            IoTPwmStop(PWM1); 
            //ptintf("val: %d duty: %d frequency: %d",val,50,Happy_Birthday[val]*100);
        }
        osDelay(1000); //==下一曲

          for (val=0;val<length_4;val++)
        {
            IoTPwmStart(PWM1,90,Jay_Love[val]*100);
            osDelay(duty_love[val]*50);  //==50用于调整节拍节奏快慢 根据喜好调
            IoTPwmStop(PWM1);
            //ptintf("val: %d duty: %d frequency: %d",val,50,Happy_Birthday[val]*100);
        }
        osDelay(1000); //==下一曲
 
    }
}

static void PwmMusicEntry(void)
{
    osThreadAttr_t attr;
    
    IoTGpioInit(PWM1_TONE_GPIO); 
    hi_io_set_func(PWM1_TONE_GPIO,HI_IO_FUNC_GPIO_9_PWM0_OUT); //==初始化 GPIO8 的pwm复用功能
    IoTPwmInit(PWM1); //==初始化pwm1

    //IoTGpioInit(9); //初始化led-IO
   // IoTGpioSetDir(9, IOT_GPIO_DIR_OUT);//设置IO方向为输出
   // IoTGpioSetOutputVal(9, 1);

    //IoTPwmStart(PWM0,50,80000); //==配置pwm0输出参数：占空比50%、频率160M/80000=2KHz 
    //IoTPwmStart(PWM1,50,80000);
    osDelay(100);   //==单位 ms

    length_1=sizeof(Happy_Birthday)/sizeof(Happy_Birthday[0]); //==计算一首音乐的周期
    length_4=sizeof(Jay_Love)/sizeof(Jay_Love[0]);

    attr.name = "PwmMusicTask";              //==指定线程运行的任务
    attr.attr_bits = 0U;                    //==
    attr.cb_mem = NULL;                     //==
    attr.cb_size = 0U;                      //==
    attr.stack_mem = NULL;                  //==
    attr.stack_size = PWM_TASK_STACK_SIZE;  //==
    attr.priority = PWM_TASK_PRIO;          //==优先权限 

    if(osThreadNew(PwmMusicTask,NULL,&attr)==NULL){
        printf("[PwmMusicEntry] creat PwmMusicTask failed!\n");
    }
}

SYS_RUN(PwmMusicEntry);